package com.smsc.headend.task.engine.handler;

import cn.hutool.json.JSONUtil;
import com.smsc.headend.module.protocol.DeviceData;
import com.smsc.headend.module.task.dto.AtomicTask;
import com.smsc.headend.module.task.dto.SubTaskGroup;
import com.smsc.headend.module.task.dto.Task;
import com.smsc.headend.task.engine.exception.UDISTaskHandlerException;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public interface TaskHandler {
    Logger log = LoggerFactory.getLogger(TaskHandler.class);

    /**
     *
     * @param task
     * @param atomicTask
     * @param cosemData
     * @param actionResult
     * @return -1 -- Error, Interrupt  1 -- Complete  0- next block  2 --re-enter to task queue
     * @throws UDISTaskHandlerException
     * @throws InvocationTargetException
     * @throws NoSuchMethodException
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    int handle(Task task, AtomicTask atomicTask, DeviceData cosemData, String actionResult) throws UDISTaskHandlerException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException;

    default Map<String, Object> getParameterMap(Task task, AtomicTask atomicTask) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("atomicTask", atomicTask);
        if(StringUtils.isNotEmpty(task.getParamJson())) {
            paramMap.putAll(JSONUtil.toBean(task.getParamJson(), Map.class));
        }
        if(StringUtils.isNotEmpty(atomicTask.getAtomicTaskParam())) {
            paramMap.putAll(JSONUtil.toBean(atomicTask.getAtomicTaskParam(), Map.class));
        }
        return paramMap;
    }

    default int handleFailure(Task task, AtomicTask atomicTask, String message) {
        log.debug("{} is not implement failure handle method", this.getClass());
        return -1;
    }

    default boolean isSubTaskGroupLastAtomicTask(Task task, AtomicTask atomicTask){
        for (SubTaskGroup g : task.getSubTaskGroups()) {
            if (g.getSubTasks().get(g.getSubTasks().size() - 1).getAtomicTaskNo().equalsIgnoreCase(atomicTask.getAtomicTaskNo())) {
                return true;
            }
        }
        return false;
    }

    default boolean isTaskLastAtomicTask(Task task, AtomicTask atomicTask) {
        List<SubTaskGroup> subTaskGroups = task.getSubTaskGroups();
        if(subTaskGroups.size() == 0) {
            return  true;
        }
        SubTaskGroup lastSubTaskGroup = subTaskGroups.get(subTaskGroups.size() - 1);
        List<AtomicTask> atomicTaskList = lastSubTaskGroup.getSubTasks();
        if(atomicTaskList.size() == 0) {
            return true;
        }
        AtomicTask lastAtomicTask = atomicTaskList.get(atomicTaskList.size() - 1);
        if(atomicTask.getAtomicTaskNo().equalsIgnoreCase(lastAtomicTask.getAtomicTaskNo())) {
            return true;
        }
        return false;
    }

}
